package com.bifang.core.excel.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.bifang.common.constant.enums.common.BoolEnum;
import com.bifang.common.constant.enums.common.ExcelTypeEnum;
import com.bifang.common.exception.AppException;
import com.bifang.common.util.ExcelFieldTreeUtil;
import com.bifang.common.vo.ExcelFieldVO;
import com.bifang.common.vo.SelectVO;
import com.bifang.common.vo.excel.ExcelModelCodeVO;
import com.bifang.common.vo.excel.ExcelModelVO;
import com.bifang.common.vo.excel.ExcelParamVO;
import com.bifang.core.excel.integration.ExcelIntegration;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Component
public class ExcelCommonUtil {
    @Autowired ExcelIntegration excelIntegration;
    public static final int DEFAULT_WINDOW_SIZE = SXSSFWorkbook.DEFAULT_WINDOW_SIZE;
    // 临时文件目录
    @Value("${spring.servlet.multipart.location}")
    private String tempPath;
    /** 生成工作簿 */
    public Workbook createWorkbook(String modelCode) {
        return this.createWorkbook(modelCode, null, null);
    }

    public Workbook createWorkbook(String modelCode, Integer rows) {
        return this.createWorkbook(modelCode, null, rows);
    }

    public Workbook createWorkbook(String modelCode, String version, Integer rows) {
        return this.createWorkbook(modelCode, version, null, rows);
    }

    public Workbook createWorkbook(
            String modelCode, String version, Map<String, List<SelectVO>> dictMap, Integer rows) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        return this.createWorkbook(excelModelVO, rows);
    }

    public Workbook createWorkbook(ExcelModelVO excelModelVO) {
        ExcelWriter excelWriter = this.createExcelWriter(excelModelVO, null);
        return excelWriter.getWorkbook();
    }

    public Workbook createWorkbook(ExcelModelVO excelModelVO, Integer rows) {
        ExcelWriter excelWriter = this.createExcelWriter(excelModelVO, rows);
        return excelWriter.getWorkbook();
    }

    public ExcelWriter createExcelWriter(ExcelModelVO excelModelVO, Integer rows) {
        List<ExcelFieldVO> fieldVOList =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        fieldVOList = ExcelFieldTreeUtil.constructTaskDTOToTree(fieldVOList);
        ExcelWriter excelWriter;
        if (rows == null) {
            rows = 10000;
        }
        String sheetName = excelModelVO.getSheetName();
        if (ExcelTypeEnum.xls.toString().equals(excelModelVO.getExcelType())) {
            if (BoolEnum.TRUE.getType().equals(excelModelVO.getBigFlag())) {
                excelWriter = ExcelUtil.getBigWriter();
                //        excelWriter = ExcelUtil.getBigWriter(fieldVOList, rows, sheetName);
            } else {
                excelWriter = ExcelUtil.getWriter();
                //        excelWriter = ExcelUtil.getWriter(fieldVOList, false, sheetName,
                // excelModelVO);
            }
        } else {
            if (BoolEnum.TRUE.getType().equals(excelModelVO.getBigFlag())) {
                excelWriter = ExcelUtil.getBigWriter();
                //        excelWriter = ExcelUtil.getBigWriter(fieldVOList, rows, sheetName);
            } else {
                excelWriter = ExcelUtil.getWriter();
                //        excelWriter = ExcelUtil.getWriter(fieldVOList, true, sheetName,
                // excelModelVO);
            }
        }
        this.addSelect(excelWriter, rows);
        return excelWriter;
    }
    /** 根据模板编号生成excel模板文件 */
    public void createExcelFile(String modelCode, File destFile) {
        this.createExcelFile(modelCode, null, destFile, null);
    }

    public void createExcelFile(String modelCode, File destFile, Integer rows) {
        this.createExcelFile(modelCode, null, destFile, rows);
    }

    public void createExcelFile(String modelCode, String version, File destFile, Integer rows) {
        this.createExcelFile(modelCode, version, null, destFile, rows);
    }

    public void createExcelFile(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            File destFile,
            Integer rows) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        List<ExcelFieldVO> fieldVOList =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        fieldVOList = ExcelFieldTreeUtil.constructTaskDTOToTree(fieldVOList);
        ExcelWriter excelWriter;
        if (rows == null) {
            rows = 10000;
        }
        String sheetName = excelModelVO.getSheetName();
        if (ExcelTypeEnum.xls.toString().equals(excelModelVO.getExcelType())) {
            if (BoolEnum.TRUE.getType().equals(excelModelVO.getBigFlag())) {
                excelWriter = ExcelUtil.getBigWriter();
                //        excelWriter = ExcelUtil.getBigWriter(fieldVOList, rows, destFile,
                // sheetName, excelModelVO);
            } else {
                excelWriter = ExcelUtil.getWriter();
                //        excelWriter = ExcelUtil.getWriter(fieldVOList, false, destFile, sheetName,
                // excelModelVO);
            }
        } else {
            if (BoolEnum.TRUE.getType().equals(excelModelVO.getBigFlag())) {
                excelWriter = ExcelUtil.getBigWriter();
                //        excelWriter = ExcelUtil.getBigWriter(fieldVOList, rows, destFile,
                // sheetName, excelModelVO);
            } else {
                excelWriter = ExcelUtil.getWriter();
                //        excelWriter = ExcelUtil.getWriter(fieldVOList, true, destFile, sheetName,
                // excelModelVO);
            }
        }
        this.addSelect(excelWriter, rows);
        excelWriter.flush();
    }

    public void addSelect(ExcelWriter excelWriter, Integer rows) {
        //    List<ExcelFieldVO> lastList = excelWriter.getLastFieldList();
        List<ExcelFieldVO> lastList = new ArrayList<>();
        //    int headerRow = excelWriter.getHeaderRow();
        int headerRow = 0;
        int rowCount = 10000;
        if (rows != null) {
            rowCount = rows;
        }
        if (!CollectionUtils.isEmpty(lastList)) {
            int size = lastList.size();
            for (int i = 0; i < size; i++) {
                ExcelFieldVO fieldVO = lastList.get(i);
                if (ExcelFieldVO.CellTypeEnum.SELECT.getType().equals(fieldVO.getCellType())
                        || ExcelFieldVO.CellTypeEnum.MULTIPLESELECT
                                .getType()
                                .equals(fieldVO.getCellType())) {
                    if (!CollectionUtils.isEmpty(fieldVO.getCodeList())) {
                        String sheetName = fieldVO.getCodeList().get(0).getFieldName();
                        List<String> selectList =
                                fieldVO.getCodeList().stream()
                                        .map(SelectVO::getDictValue)
                                        .collect(Collectors.toList());
                        //            excelWriter.addSelect(
                        //                headerRow,
                        //                rowCount,
                        //                i,
                        //                i,
                        //                sheetName,
                        //                selectList.toArray(new String[selectList.size()]));
                    }
                }
            }
            //      excelWriter.setStyle(lastList, headerRow, rowCount);
        }
    }

    /** 根据模板编号生成excel文件到指定文件 */
    public void createExcel(String modelCode, String destFilePath) {
        this.createExcel(modelCode, destFilePath, null, null, null);
    }

    public void createExcel(
            String modelCode, String destFilePath, Map<String, List<SelectVO>> dictMap) {
        this.createExcel(modelCode, destFilePath, null, null, dictMap);
    }

    public void createExcel(String modelCode, String destFilePath, Integer rows) {
        this.createExcel(modelCode, destFilePath, null, rows);
    }

    public void createExcel(String modelCode, String destFilePath, String version) {
        ExcelWriter excelWriter = this.createExcelWrite(modelCode, destFilePath, version);
        excelWriter.flush();
    }

    public void createExcel(
            String modelCode,
            String destFilePath,
            String version,
            Map<String, List<SelectVO>> dictMap) {
        ExcelWriter excelWriter = this.createExcelWrite(modelCode, destFilePath, version, dictMap);
        excelWriter.flush();
    }

    public void createExcel(String modelCode, String destFilePath, String version, Integer rows) {
        ExcelWriter excelWriter =
                this.createExcelWrite(modelCode, destFilePath, version, rows, null);
        excelWriter.flush();
    }

    public void createExcel(
            String modelCode,
            String destFilePath,
            String version,
            Integer rows,
            Map<String, List<SelectVO>> dictMap) {
        ExcelWriter excelWriter =
                this.createExcelWrite(modelCode, destFilePath, version, rows, dictMap);
        excelWriter.flush();
    }

    public ExcelWriter createExcelWrite(String modelCode, String destFilePath) {
        ExcelModelVO excelModelVO = getModel(modelCode, null);
        return this.createExcelWrite(excelModelVO, destFilePath, null);
    }

    public ExcelWriter createExcelWrite(
            String modelCode, String destFilePath, Map<String, List<SelectVO>> dictMap) {
        ExcelModelVO excelModelVO = getModel(modelCode, null, dictMap);
        return this.createExcelWrite(excelModelVO, destFilePath, null);
    }

    public ExcelWriter createExcelWrite(String modelCode, String destFilePath, String version) {
        ExcelModelVO excelModelVO = getModel(modelCode, version);
        return this.createExcelWrite(excelModelVO, destFilePath, null);
    }

    public ExcelWriter createExcelWrite(
            String modelCode,
            String destFilePath,
            String version,
            Map<String, List<SelectVO>> dictMap) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        return this.createExcelWrite(excelModelVO, destFilePath, null);
    }

    public ExcelWriter createExcelWrite(
            String modelCode,
            String destFilePath,
            String version,
            Integer rows,
            Map<String, List<SelectVO>> dictMap) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        return this.createExcelWrite(excelModelVO, destFilePath, rows);
    }

    public ExcelWriter createExcelWrite(
            ExcelModelVO excelModelVO, String destFilePath, Integer rows) {
        List<ExcelFieldVO> fieldVOList =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        fieldVOList = ExcelFieldTreeUtil.constructTaskDTOToTree(fieldVOList);
        ExcelWriter excelWriter;
        String sheetName = excelModelVO.getSheetName();
        if (ExcelTypeEnum.xls.toString().equals(excelModelVO.getExcelType())) {
            if (BoolEnum.TRUE.getType().equals(excelModelVO.getBigFlag())) {
                excelWriter = ExcelUtil.getBigWriter();
                //        excelWriter = ExcelUtil.getBigWriter(fieldVOList, destFilePath, sheetName,
                // excelModelVO);
            } else {
                excelWriter = ExcelUtil.getWriter();
                //        excelWriter =
                //            ExcelUtil.getWriter(fieldVOList, false, destFilePath, sheetName,
                // excelModelVO);
            }
        } else {
            if (BoolEnum.TRUE.getType().equals(excelModelVO.getBigFlag())) {
                excelWriter = ExcelUtil.getBigWriter();
                //        excelWriter = ExcelUtil.getBigWriter(fieldVOList, destFilePath, sheetName,
                // excelModelVO);
            } else {
                excelWriter = ExcelUtil.getWriter();
                //        excelWriter = ExcelUtil.getWriter(fieldVOList, true, destFilePath,
                // sheetName, excelModelVO);
            }
        }
        this.addSelect(excelWriter, rows);
        return excelWriter;
    }

    /** 下载模板 */
    public void downloadModel(ExcelModelCodeVO vo, HttpServletResponse response) {
        this.downloadModel(
                vo.getModelCode(), vo.getVersion(), vo.getDictMap(), vo.getRows(), response);
    }

    public void downloadModel(String modelCode, HttpServletResponse response) {
        this.downloadModel(modelCode, null, response);
    }

    public void downloadModel(String modelCode, String version, HttpServletResponse response) {
        this.downloadModel(modelCode, version, null, response);
    }

    public void downloadModel(
            String modelCode, String version, Integer rows, HttpServletResponse response) {
        this.downloadModel(modelCode, version, null, rows, response);
    }

    public void downloadModel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            Integer rows,
            HttpServletResponse response) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        String filename =
                excelModelVO.getModelName()
                        + "."
                        + (StringUtils.isBlank(excelModelVO.getExcelType())
                                ? "xls"
                                : excelModelVO.getExcelType());
        Workbook workbook = this.createWorkbook(excelModelVO, rows);
        ByteArrayOutputStream os = null;
        ServletOutputStream outputStream = null;
        try {
            os = new ByteArrayOutputStream();
            workbook.write(os);
            byte[] bytes = os.toByteArray();
            outputStream = response.getOutputStream();
            response.setContentType("application/octet-stream;charset=utf-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader(
                    "Content-disposition",
                    "attachment;filename= " + java.net.URLEncoder.encode(filename, "UTF-8"));
            outputStream.write(bytes);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /** 下载excel */
    /** 传入map生成excel到服务器 */
    public String createExcel(String modelCode, List<Map<String, Object>> dataList) {
        ExcelModelVO excelModelVO = getModel(modelCode, null);
        return this.createExcel(excelModelVO, dataList);
    }

    public String createExcel(
            String modelCode,
            Map<String, List<SelectVO>> dictMap,
            List<Map<String, Object>> dataList) {
        ExcelModelVO excelModelVO = getModel(modelCode, null, dictMap);
        return this.createExcel(excelModelVO, dataList);
    }

    public String createExcel(
            String modelCode, List<Map<String, Object>> dataList, String destFilePath) {
        ExcelModelVO excelModelVO = getModel(modelCode, null);
        return this.createExcel(excelModelVO, dataList, destFilePath);
    }

    public String createExcel(ExcelModelCodeVO vo, List<Map<String, Object>> dataList) {
        ExcelModelVO excelModelVO = getModel(vo.getModelCode(), vo.getVersion(), vo.getDictMap());
        return this.createExcel(excelModelVO, dataList);
    }

    public String createExcel(
            ExcelModelCodeVO vo, List<Map<String, Object>> dataList, String destFilePath) {
        ExcelModelVO excelModelVO = getModel(vo.getModelCode(), vo.getVersion(), vo.getDictMap());
        return this.createExcel(excelModelVO, dataList, destFilePath);
    }

    public void downloadExcel(
            ExcelModelCodeVO vo, List<Map<String, Object>> dataList, HttpServletResponse response) {
        this.downloadExcel(
                vo.getModelCode(), vo.getVersion(), vo.getDictMap(), dataList, null, response);
    }

    public void downloadExcel(
            ExcelModelCodeVO vo,
            List<Map<String, Object>> dataList,
            String fileName,
            HttpServletResponse response) {
        this.downloadExcel(
                vo.getModelCode(), vo.getVersion(), vo.getDictMap(), dataList, fileName, response);
    }

    public void downloadExcel(
            String modelCode, List<Map<String, Object>> dataList, HttpServletResponse response) {
        this.downloadExcel(modelCode, null, null, dataList, null, response);
    }

    public void downloadExcel(
            String modelCode,
            List<Map<String, Object>> dataList,
            String fileName,
            HttpServletResponse response) {
        this.downloadExcel(modelCode, null, null, dataList, fileName, response);
    }

    public void downloadExcel(
            String modelCode,
            String version,
            List<Map<String, Object>> dataList,
            String fileName,
            HttpServletResponse response) {
        this.downloadExcel(modelCode, version, null, dataList, fileName, response);
    }

    public void downloadExcel(
            String modelCode,
            Map<String, List<SelectVO>> dictMap,
            List<Map<String, Object>> dataList,
            String fileName,
            HttpServletResponse response) {
        this.downloadExcel(modelCode, null, dictMap, dataList, fileName, response);
    }

    public void downloadExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            List<Map<String, Object>> dataList,
            String fileName,
            HttpServletResponse response) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        String destFilePath = this.createExcel(excelModelVO, dataList);
        if (StringUtils.isBlank(fileName)) {
            fileName =
                    excelModelVO.getModelName()
                            + "_"
                            + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN)
                            + "."
                            + (StringUtils.isBlank(excelModelVO.getExcelType())
                                    ? "xls"
                                    : excelModelVO.getExcelType());
        }
        File file = FileUtil.file(destFilePath);
        try {
            //      ServletUtil.write(response, file, "application/octet-stream;charset=utf-8",
            // fileName);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            FileUtil.del(destFilePath);
        }
    }
    /** 根据模板、数据、路径生成excel文件 */
    public String createExcel(ExcelModelVO excelModelVO, List<Map<String, Object>> dataList) {
        String destFilePath =
                this.tempPath + "/" + IdUtil.fastSimpleUUID() + "." + excelModelVO.getExcelType();
        ExcelWriter excelWriter =
                this.createExcelWrite(excelModelVO, destFilePath, dataList.size());
        excelWriter.write(dataList);
        excelWriter.flush();
        return destFilePath;
    }
    /** 根据模板、数据、路径生成excel文件 */
    public String createExcel(
            ExcelModelVO excelModelVO, List<Map<String, Object>> dataList, String destFilePath) {
        if (StringUtils.isBlank(destFilePath)) {
            destFilePath =
                    this.tempPath
                            + "/"
                            + IdUtil.fastSimpleUUID()
                            + "_"
                            + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN)
                            + "."
                            + excelModelVO.getExcelType();
        }
        ExcelWriter excelWriter =
                this.createExcelWrite(excelModelVO, destFilePath, dataList.size());
        excelWriter.setOnlyAlias(false);
        excelWriter.write(dataList);
        excelWriter.flush();
        return destFilePath;
    }
    /** 传入bean导出数据 */
    public void downloadExcelBean(
            ExcelModelCodeVO vo, List<Object> dataList, HttpServletResponse response) {
        this.downloadExcelBean(
                vo.getModelCode(), vo.getVersion(), vo.getDictMap(), dataList, null, response);
    }

    public void downloadExcelBean(
            ExcelModelCodeVO vo,
            List<Object> dataList,
            String fileName,
            HttpServletResponse response) {
        this.downloadExcelBean(
                vo.getModelCode(), vo.getVersion(), vo.getDictMap(), dataList, fileName, response);
    }
    /** 传入bean生成excel到服务器 */
    public String createExcelBean(ExcelModelCodeVO vo, List<Object> dataList) {
        ExcelModelVO excelModelVO = getModel(vo.getModelCode(), vo.getVersion(), vo.getDictMap());
        return this.createExcelBean(excelModelVO, dataList);
    }

    public String createExcelBean(ExcelModelCodeVO vo, List<Object> dataList, String destFilePath) {
        ExcelModelVO excelModelVO = getModel(vo.getModelCode(), vo.getVersion(), vo.getDictMap());
        return this.createExcelBean(excelModelVO, dataList, destFilePath);
    }
    /** 传入bean导出数据 */
    public void downloadExcelBean(
            String modelCode, List<Object> dataList, HttpServletResponse response) {
        this.downloadExcelBean(modelCode, null, dataList, null, response);
    }

    public void downloadExcelBean(
            String modelCode, String version, List<Object> dataList, HttpServletResponse response) {
        this.downloadExcelBean(modelCode, version, null, dataList, null, response);
    }

    public void downloadExcelBean(
            String modelCode,
            List<Object> dataList,
            String fileName,
            HttpServletResponse response) {
        this.downloadExcelBean(modelCode, null, dataList, fileName, response);
    }

    public void downloadExcelBean(
            String modelCode,
            Map<String, List<SelectVO>> dictMap,
            List<Object> dataList,
            String fileName,
            HttpServletResponse response) {
        this.downloadExcelBean(modelCode, null, dictMap, dataList, fileName, response);
    }
    /** 传入bean生成excel到服务器 */
    public String createExcelBean(String modelCode, List<Object> dataList) {
        ExcelModelVO excelModelVO = getModel(modelCode, null);
        return this.createExcelBean(excelModelVO, dataList);
    }

    public String createExcelBean(String modelCode, List<Object> dataList, String destFilePath) {
        ExcelModelVO excelModelVO = getModel(modelCode, null);
        return this.createExcelBean(excelModelVO, dataList, destFilePath);
    }

    public String createExcelBean(
            String modelCode,
            Map<String, List<SelectVO>> dictMap,
            List<Object> dataList,
            String destFilePath) {
        ExcelModelVO excelModelVO = getModel(modelCode, null, dictMap);
        return this.createExcelBean(excelModelVO, dataList, destFilePath);
    }

    public String createExcelBean(
            String modelCode, String version, List<Object> dataList, String destFilePath) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, null);
        return this.createExcelBean(excelModelVO, dataList, destFilePath);
    }

    public void downloadExcelBean(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            List<Object> dataList,
            String fileName,
            HttpServletResponse response) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        String destFilePath = this.createExcelBean(excelModelVO, dataList);
        if (StringUtils.isBlank(fileName)) {
            fileName =
                    excelModelVO.getModelName()
                            + "_"
                            + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN)
                            + "."
                            + (StringUtils.isBlank(excelModelVO.getExcelType())
                                    ? "xls"
                                    : excelModelVO.getExcelType());
        }
        File file = FileUtil.file(destFilePath);
        try {
            //      ServletUtil.write(response, file, "application/octet-stream;charset=utf-8",
            // fileName);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            FileUtil.del(destFilePath);
        }
    }
    /** 根据模板、数据、路径生成excel文件 */
    public String createExcelBean(ExcelModelVO excelModelVO, List<Object> dataList) {
        String destFilePath =
                this.tempPath + "/" + IdUtil.fastSimpleUUID() + "." + excelModelVO.getExcelType();
        ExcelWriter excelWriter =
                this.createExcelWrite(excelModelVO, destFilePath, dataList.size());
        excelWriter.write(dataList);
        excelWriter.flush();
        return destFilePath;
    }
    /** 根据模板、数据、路径生成excel文件 */
    public String createExcelBean(
            ExcelModelVO excelModelVO, List<Object> dataList, String destFilePath) {
        if (StringUtils.isBlank(destFilePath)) {
            destFilePath =
                    this.tempPath
                            + "/"
                            + IdUtil.fastSimpleUUID()
                            + "_"
                            + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_PATTERN)
                            + "."
                            + excelModelVO.getExcelType();
        }
        ExcelWriter excelWriter =
                this.createExcelWrite(excelModelVO, destFilePath, dataList.size());
        excelWriter.setOnlyAlias(false);
        excelWriter.write(dataList);
        excelWriter.flush();
        return destFilePath;
    }
    /** 读取excel 通过文件 */
    public List<Map<String, Object>> readExcel(ExcelModelCodeVO excelModelCodeVO, File file) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                file);
    }

    public List<Map<String, Object>> readExcel(
            ExcelModelCodeVO excelModelCodeVO, File file, boolean ignoreEmptyRow) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                file,
                ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(String modelCode, File file) {
        return this.readExcel(modelCode, null, file);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, File file, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, null, file, ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(String modelCode, String version, File file) {
        return this.readExcel(modelCode, version, null, file);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, String version, File file, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, version, null, file, ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, String version, Map<String, List<SelectVO>> dictMap, File file) {
        return this.readExcel(modelCode, version, dictMap, file, true);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            File file,
            boolean ignoreEmptyRow) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        List<ExcelFieldVO> headers =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        headers = ExcelFieldTreeUtil.constructTaskDTOToTree(headers);
        ExcelReader excelReader = ExcelUtil.getReader(file);
        excelReader.setIgnoreEmptyRow(ignoreEmptyRow);
        //    List<Map<String, Object>> list = excelReader.readAll(headers);
        return new ArrayList<>();
    }
    /** 读取excel 通过文件路径 */
    public List<Map<String, Object>> readExcel(
            ExcelModelCodeVO excelModelCodeVO, String excelFilePath) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                excelFilePath);
    }

    public List<Map<String, Object>> readExcel(
            ExcelModelCodeVO excelModelCodeVO, String excelFilePath, boolean ignoreEmptyRow) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                excelFilePath,
                ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(String modelCode, String excelFilePath) {
        return this.readExcel(modelCode, null, excelFilePath);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, String excelFilePath, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, null, excelFilePath, ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, String version, String excelFilePath) {
        return this.readExcel(modelCode, version, null, excelFilePath);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, String version, String excelFilePath, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, version, null, excelFilePath, ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            String excelFilePath) {
        return this.readExcel(modelCode, version, dictMap, excelFilePath, true);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            String excelFilePath,
            boolean ignoreEmptyRow) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        List<ExcelFieldVO> headers =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        headers = ExcelFieldTreeUtil.constructTaskDTOToTree(headers);
        ExcelReader excelReader = ExcelUtil.getReader(excelFilePath);
        excelReader.setIgnoreEmptyRow(ignoreEmptyRow);
        //    List<Map<String, Object>> list = excelReader.readAll(headers);
        return new ArrayList<>();
    }
    /** 读取excel 通过输入流 */
    public List<Map<String, Object>> readExcel(
            ExcelModelCodeVO excelModelCodeVO, InputStream bookStream) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                bookStream);
    }

    public List<Map<String, Object>> readExcel(
            ExcelModelCodeVO excelModelCodeVO, InputStream bookStream, boolean ignoreEmptyRow) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                bookStream,
                ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(String modelCode, InputStream bookStream) {
        return this.readExcel(modelCode, null, bookStream);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, InputStream bookStream, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, null, bookStream, ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, String version, InputStream bookStream) {
        return this.readExcel(modelCode, version, null, bookStream);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode, String version, InputStream bookStream, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, version, null, bookStream, ignoreEmptyRow);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            InputStream bookStream) {
        return this.readExcel(modelCode, version, dictMap, bookStream, true);
    }

    public List<Map<String, Object>> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            InputStream bookStream,
            boolean ignoreEmptyRow) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        List<ExcelFieldVO> headers =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        headers = ExcelFieldTreeUtil.constructTaskDTOToTree(headers);
        ExcelReader excelReader = ExcelUtil.getReader(bookStream);
        excelReader.setIgnoreEmptyRow(ignoreEmptyRow);
        //    List<Map<String, Object>> list = excelReader.readAll(headers);
        return new ArrayList<>();
    }
    /** 读取excel 通过文件 返回实体 */
    public <T> List<T> readExcel(ExcelModelCodeVO excelModelCodeVO, File file, Class<T> beanType) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                file,
                beanType);
    }

    public <T> List<T> readExcel(
            ExcelModelCodeVO excelModelCodeVO,
            File file,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                file,
                beanType,
                ignoreEmptyRow);
    }

    public <T> List<T> readExcel(String modelCode, File file, Class<T> beanType) {
        return this.readExcel(modelCode, null, file, beanType);
    }

    public <T> List<T> readExcel(
            String modelCode, File file, Class<T> beanType, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, null, file, beanType, ignoreEmptyRow);
    }

    public <T> List<T> readExcel(String modelCode, String version, File file, Class<T> beanType) {
        return this.readExcel(modelCode, version, null, file, beanType);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            File file,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, version, null, file, beanType, ignoreEmptyRow);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            File file,
            Class<T> beanType) {
        return this.readExcel(modelCode, version, dictMap, file, beanType, true);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            File file,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        List<ExcelFieldVO> headers =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        headers = ExcelFieldTreeUtil.constructTaskDTOToTree(headers);
        ExcelReader excelReader = ExcelUtil.getReader(file);
        excelReader.setIgnoreEmptyRow(ignoreEmptyRow);
        //    List<T> list = excelReader.readAll(beanType, headers);
        return new ArrayList<>();
    }
    /** 读取excel 通过文件路径 返回实体 */
    public <T> List<T> readExcel(
            ExcelModelCodeVO excelModelCodeVO, String excelFilePath, Class<T> beanType) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                excelFilePath,
                beanType);
    }

    public <T> List<T> readExcel(
            ExcelModelCodeVO excelModelCodeVO,
            String excelFilePath,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                excelFilePath,
                beanType,
                ignoreEmptyRow);
    }

    public <T> List<T> readExcel(String modelCode, String excelFilePath, Class<T> beanType) {
        return this.readExcel(modelCode, null, excelFilePath, beanType);
    }

    public <T> List<T> readExcel(
            String modelCode, String excelFilePath, Class<T> beanType, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, null, excelFilePath, beanType, ignoreEmptyRow);
    }

    public <T> List<T> readExcel(
            String modelCode, String version, String excelFilePath, Class<T> beanType) {
        return this.readExcel(modelCode, version, null, excelFilePath, beanType);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            String excelFilePath,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, version, null, excelFilePath, beanType, ignoreEmptyRow);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            String excelFilePath,
            Class<T> beanType) {
        return this.readExcel(modelCode, version, dictMap, excelFilePath, beanType, true);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            String excelFilePath,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        List<ExcelFieldVO> headers =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        headers = ExcelFieldTreeUtil.constructTaskDTOToTree(headers);
        ExcelReader excelReader = ExcelUtil.getReader(excelFilePath);
        excelReader.setIgnoreEmptyRow(ignoreEmptyRow);
        //    List<T> list = excelReader.readAll(beanType, headers);
        return new ArrayList<>();
    }
    /** 读取excel 通过输入流 返回实体 */
    public <T> List<T> readExcel(
            ExcelModelCodeVO excelModelCodeVO, InputStream bookStream, Class<T> beanType) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                bookStream,
                beanType);
    }

    public <T> List<T> readExcel(
            ExcelModelCodeVO excelModelCodeVO,
            InputStream bookStream,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        return this.readExcel(
                excelModelCodeVO.getModelCode(),
                excelModelCodeVO.getVersion(),
                excelModelCodeVO.getDictMap(),
                bookStream,
                beanType,
                ignoreEmptyRow);
    }

    public <T> List<T> readExcel(String modelCode, InputStream bookStream, Class<T> beanType) {
        return this.readExcel(modelCode, null, null, bookStream, beanType);
    }

    public <T> List<T> readExcel(
            String modelCode, InputStream bookStream, Class<T> beanType, boolean ignoreEmptyRow) {
        return this.readExcel(modelCode, null, null, bookStream, beanType, ignoreEmptyRow);
    }

    public <T> List<T> readExcel(
            String modelCode, String version, InputStream bookStream, Class<T> beanType) {
        return this.readExcel(modelCode, version, null, bookStream, beanType);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            InputStream bookStream,
            Class<T> beanType) {

        return readExcel(modelCode, version, dictMap, bookStream, beanType, true);
    }

    public <T> List<T> readExcel(
            String modelCode,
            String version,
            Map<String, List<SelectVO>> dictMap,
            InputStream bookStream,
            Class<T> beanType,
            boolean ignoreEmptyRow) {
        ExcelModelVO excelModelVO = getModel(modelCode, version, dictMap);
        List<ExcelFieldVO> headers =
                Convert.toList(ExcelFieldVO.class, excelModelVO.getParamVOList());
        headers = ExcelFieldTreeUtil.constructTaskDTOToTree(headers);
        ExcelReader excelReader = ExcelUtil.getReader(bookStream);
        excelReader.setIgnoreEmptyRow(ignoreEmptyRow);
        //    List<T> list = excelReader.readAll(beanType, headers);
        return new ArrayList<>();
    }

    public ExcelModelVO getModel(ExcelModelCodeVO vo) {
        return this.getModel(vo);
    }

    public ExcelModelVO getModel(String modelCode, String version) {
        return this.getModel(modelCode, version, null);
    }

    public ExcelModelVO getModel(
            String modelCode, String version, Map<String, List<SelectVO>> dictMap) {
        ExcelModelVO excelModelVO = excelIntegration.queryByCode(modelCode, version, dictMap);
        if (excelModelVO == null) {
            throw new AppException("未找到模板信息");
        }
        if (CollectionUtils.isEmpty(excelModelVO.getParamVOList())) {
            throw new AppException("未配置参数信息");
        }
        if (StringUtils.isBlank(excelModelVO.getExcelType())) {
            excelModelVO.setExcelType(ExcelTypeEnum.xls.toString());
        }
        return excelModelVO;
    }

    public List<ExcelFieldVO> getFieldList(List<ExcelParamVO> paramVOList) {
        List<ExcelFieldVO> fieldVOList = new ArrayList<>();
        for (ExcelParamVO excelParamVO : paramVOList) {
            ExcelFieldVO fieldVO = Convert.convert(ExcelFieldVO.class, excelParamVO);
            if (BoolEnum.TRUE.getType().equals(excelParamVO.getWrapText())) {
                fieldVO.setWrapText(true);
            } else {
                fieldVO.setWrapText(false);
            }
        }
        return fieldVOList;
    }
}
